using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Calendar;

using GymManager.Business;
using GymManager.Exception;
using GymManager.Properties;

namespace GymManager.Presentation.Schedule
{
    public partial class ScheduleForm : Form
    {
        /// <summary>
        /// Default Constructor
        /// </summary>
        public ScheduleForm()
        {
            InitializeComponent();
        }

        #region Form Events
        /// <summary>
        /// Method responsible by loading information about the schedule
        /// </summary>
        private void ScheduleForm_Load(object sender, EventArgs e)
        {
            // setting the first day of the calendar, as the first monday of the current week
            DateTime firstWorkingDay = DateTime.Now;
            firstWorkingDay = firstWorkingDay.AddDays(DayOfWeek.Monday - firstWorkingDay.DayOfWeek);
            calendarDayView.StartDate = firstWorkingDay;

            // setting event treatement for new appointments
            calendarDayView.OnResolveAppointments += new EventHandler<ResolveAppointmentsEventArgs>(this.calendarDayView_ResolveAppointments);

        }
        #endregion

        #region Button Events
        /// <summary>
        /// Method responsible by closing the form
        /// </summary>
        private void btnOK_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }
        #endregion

        #region Calendar Events
        /// <summary>
        /// Method responsible by assign the appointments to the calendar
        /// </summary>
        private void calendarDayView_ResolveAppointments(object sender, ResolveAppointmentsEventArgs args)
        {
            // assign appointment list fo the calendar
            IList<Appointment> appointmentList = generateModalitySchedule();
            args.Appointments = (List<Appointment>)appointmentList;
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// Method responsible by loading information from database into the right way. The information will
        /// be converted to readable appointments for calendar view
        /// </summary>
        /// <returns>List of appointments in according to the calendar view</returns>
        private IList<Appointment> generateModalitySchedule()
        {
            // appointment list
            IList<Appointment> appointmentList = new List<Appointment>();

            try
            {
                // retrieving information from database
                StudentModalityScheduleServices scheduleServices = new StudentModalityScheduleServices();
                IDictionary<GymManager.Persistence.VO.Modality, IDictionary<String, IList<String>>> studentClassStructure = scheduleServices.getStudentsByClass();
                
                // transposing business information into presentation
                if (studentClassStructure != null && studentClassStructure.Count > 0)
                {
                    // infra-estructure objects
                    Appointment newAppointment = null;
                    IDictionary<String, IList<String>> modalitySchedule = null;
                    IList<String> studentList = null;
                    String classTime = String.Empty;
                    Int32 classDayOfWeek = -1;
                    DateTime appointmentStartDate = DateTime.Today, appointmentEndDate = DateTime.Today;
                    TimeSpan appointmentStartTime = TimeSpan.Zero;

                    // processing each modality schedule
                    foreach (GymManager.Persistence.VO.Modality modality in studentClassStructure.Keys)
                    {
                        // obtain the schedule associated to the schedule
                        modalitySchedule = studentClassStructure[modality];

                        // for each item in the modality schedule create a new appointment
                        if (modalitySchedule != null && modalitySchedule.Count > 0)
                        {
                            foreach (String scheduleInfo in modalitySchedule.Keys)
                            {
                                // break the key information
                                classDayOfWeek = Convert.ToInt32(scheduleInfo.Split('-')[0]);
                                classTime = scheduleInfo.Split('-')[1];

                                // setting initial properties
                                newAppointment = new Appointment(); newAppointment.Subject = String.Empty;
                                newAppointment.AllDayEvent = false; newAppointment.DrawBorder = true; newAppointment.Recurring = false;

                                // setting student information
                                studentList = modalitySchedule[scheduleInfo];
                                foreach (String studentName in studentList)
                                {
                                    newAppointment.Subject = newAppointment.Subject + studentName + ", ";
                                }
                                newAppointment.Subject = newAppointment.Subject.Substring(0, newAppointment.Subject.Length - 2);

                                // calculating appointment's begin and end dates
                                appointmentStartTime = TimeSpan.Parse(classTime);
                                appointmentStartDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, appointmentStartTime.Hours, appointmentStartTime.Minutes, 0);
                                appointmentStartDate = appointmentStartDate.AddDays(classDayOfWeek - ((Int32)appointmentStartDate.DayOfWeek));
                                appointmentEndDate = appointmentStartDate.AddMinutes(Settings.Default.ClassDuration);

                                // setting time and date information
                                newAppointment.StartDate = appointmentStartDate;
                                newAppointment.EndDate = appointmentEndDate;

                                // if the number of students has already been reached, show the lock mark indicating that a class is full
                                newAppointment.Locked = (studentList.Count == modality.MaxNumberOfStudentsAllowed);

                                // set the color of the appointment (in according to the modality)
                                newAppointment.Color = Color.FromArgb( modality.ScheduleColor.Value );

                                // adding the appointment to the list
                                appointmentList.Add(newAppointment);
                            }
                        }
                    }
                }
            }
            catch (BusinessException)
            {
                MessageBox.Show("Problemas na montagem da agenda.", "Agenda", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return appointmentList;
        }
        #endregion
    }
}